"""
数据源管理Pydantic模式
用于API请求和响应的数据验证
"""

from pydantic import BaseModel, Field, field_validator, model_validator
from typing import Optional, List, Dict, Any
from datetime import datetime
from enum import Enum
import re

from app.models.datasource import DatabaseType, TestStatus


class DataSourceBase(BaseModel):
    """数据源基础模式"""
    name: str = Field(..., min_length=1, max_length=100, description="数据源名称（唯一标识）")
    display_name: str = Field(..., min_length=1, max_length=100, description="显示名称")
    description: Optional[str] = Field(None, max_length=1000, description="数据源描述")
    type: DatabaseType = Field(..., description="数据库类型")
    host: str = Field(..., min_length=1, max_length=255, description="主机地址")
    port: int = Field(..., ge=1, le=65535, description="端口号")
    database_name: str = Field(..., min_length=1, max_length=100, description="数据库名称")
    username: str = Field(..., min_length=1, max_length=100, description="用户名")
    connection_params: Optional[Dict[str, Any]] = Field(None, description="额外连接参数")
    is_active: bool = Field(True, description="是否启用")
    connection_timeout: int = Field(30, ge=5, le=300, description="连接超时时间（秒）")
    max_connections: int = Field(10, ge=1, le=100, description="最大连接数")

    @field_validator('name')
    @classmethod
    def validate_name(cls, v):
        """验证数据源名称"""
        if not v.replace('_', '').replace('-', '').isalnum():
            raise ValueError('数据源名称只能包含字母、数字、下划线和连字符')
        return v

    @field_validator('host')
    @classmethod
    def validate_host(cls, v):
        """验证主机地址"""
        # 简单的IP地址或域名验证
        ip_pattern = r'^(\d{1,3}\.){3}\d{1,3}$'
        domain_pattern = r'^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$'

        if not (re.match(ip_pattern, v) or re.match(domain_pattern, v) or v == 'localhost'):
            raise ValueError('请输入有效的IP地址或域名')
        return v

    @model_validator(mode='after')
    def validate_port_for_database_type(self):
        """根据数据库类型验证默认端口"""
        db_type = self.type
        port = self.port

        default_ports = {
            DatabaseType.MYSQL: 3306,
            DatabaseType.POSTGRESQL: 5432,
            DatabaseType.ORACLE: 1521,
            DatabaseType.SQLSERVER: 1433,
            DatabaseType.DORIS: 9030,
        }

        if db_type and port:
            expected_port = default_ports.get(db_type)
            if expected_port and port != expected_port:
                # 这里只是警告，不强制要求使用默认端口
                pass

        return self


class DataSourceCreate(DataSourceBase):
    """创建数据源模式"""
    password: str = Field(..., min_length=1, max_length=255, description="密码")

    @field_validator('password')
    @classmethod
    def validate_password(cls, v):
        """验证密码"""
        if len(v.strip()) == 0:
            raise ValueError('密码不能为空')
        return v


class DataSourceUpdate(BaseModel):
    """更新数据源模式"""
    display_name: Optional[str] = Field(None, min_length=1, max_length=100, description="显示名称")
    description: Optional[str] = Field(None, max_length=1000, description="数据源描述")
    host: Optional[str] = Field(None, min_length=1, max_length=255, description="主机地址")
    port: Optional[int] = Field(None, ge=1, le=65535, description="端口号")
    database_name: Optional[str] = Field(None, min_length=1, max_length=100, description="数据库名称")
    username: Optional[str] = Field(None, min_length=1, max_length=100, description="用户名")
    password: Optional[str] = Field(None, min_length=1, max_length=255, description="密码")
    connection_params: Optional[Dict[str, Any]] = Field(None, description="额外连接参数")
    is_active: Optional[bool] = Field(None, description="是否启用")
    connection_timeout: Optional[int] = Field(None, ge=5, le=300, description="连接超时时间（秒）")
    max_connections: Optional[int] = Field(None, ge=1, le=100, description="最大连接数")


class DataSourceResponse(BaseModel):
    """数据源响应模式"""
    id: int
    name: str
    display_name: str
    description: Optional[str]
    type: DatabaseType
    host: str
    port: int
    database_name: str
    username: str
    connection_params: Optional[Dict[str, Any]]
    is_active: bool
    connection_timeout: int
    max_connections: int
    last_test_at: Optional[datetime]
    last_test_status: TestStatus
    last_test_message: Optional[str]
    connection_string_masked: str
    is_healthy: bool
    
    # 审计字段
    created_by: Optional[int]
    updated_by: Optional[int]
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


class DataSourceListResponse(BaseModel):
    """数据源列表响应模式"""
    datasources: List[DataSourceResponse]
    total: int
    page: int
    page_size: int
    total_pages: int


class ConnectionTestRequest(BaseModel):
    """连接测试请求模式"""
    type: DatabaseType = Field(..., description="数据库类型")
    host: str = Field(..., min_length=1, max_length=255, description="主机地址")
    port: int = Field(..., ge=1, le=65535, description="端口号")
    database_name: str = Field(..., min_length=1, max_length=100, description="数据库名称")
    username: str = Field(..., min_length=1, max_length=100, description="用户名")
    password: str = Field(..., min_length=1, max_length=255, description="密码")
    connection_params: Optional[Dict[str, Any]] = Field(None, description="额外连接参数")
    connection_timeout: int = Field(30, ge=5, le=300, description="连接超时时间（秒）")


class ConnectionTestResponse(BaseModel):
    """连接测试响应模式"""
    success: bool
    message: str
    response_time: Optional[int] = Field(None, description="响应时间（毫秒）")
    error_details: Optional[Dict[str, Any]] = None
    database_info: Optional[Dict[str, Any]] = None


class TestLogResponse(BaseModel):
    """测试日志响应模式"""
    id: int
    test_status: TestStatus
    test_message: Optional[str]
    response_time: Optional[int]
    error_details: Optional[Dict[str, Any]]
    tested_by: Optional[int]
    tested_at: datetime

    class Config:
        from_attributes = True


class BatchTestRequest(BaseModel):
    """批量测试请求模式"""
    datasource_ids: List[int] = Field(..., min_items=1, max_items=50, description="数据源ID列表")


class BatchTestResponse(BaseModel):
    """批量测试响应模式"""
    results: List[Dict[str, Any]]
    success_count: int
    failed_count: int
    total_count: int


class BatchOperationRequest(BaseModel):
    """批量操作请求模式"""
    datasource_ids: List[int] = Field(..., min_items=1, max_items=50, description="数据源ID列表")
    operation: str = Field(..., description="操作类型：delete, enable, disable")

    @field_validator('operation')
    @classmethod
    def validate_operation(cls, v):
        """验证操作类型"""
        allowed_operations = ['delete', 'enable', 'disable']
        if v not in allowed_operations:
            raise ValueError(f'操作类型必须是以下之一：{", ".join(allowed_operations)}')
        return v


class DataSourceStats(BaseModel):
    """数据源统计模式"""
    total_count: int
    active_count: int
    inactive_count: int
    healthy_count: int
    unhealthy_count: int
    type_distribution: Dict[str, int]
    recent_test_results: List[Dict[str, Any]]


class DataSourceImportRequest(BaseModel):
    """数据源导入请求模式"""
    datasources: List[DataSourceCreate] = Field(..., min_items=1, max_items=100, description="数据源列表")
    overwrite_existing: bool = Field(False, description="是否覆盖已存在的数据源")


class DataSourceImportResponse(BaseModel):
    """数据源导入响应模式"""
    success_count: int
    failed_count: int
    skipped_count: int
    total_count: int
    errors: List[Dict[str, Any]]


class DataSourceExportResponse(BaseModel):
    """数据源导出响应模式"""
    datasources: List[Dict[str, Any]]
    export_time: datetime
    total_count: int
